#pragma once
#include"Channel.hpp"
#include"Poller.hpp"
#include<sys/eventfd.h>
#include<thread>
#include<mutex>
#include<memory>
#include<errno.h>
#include"TimerQueue.hpp"




class EventLoop
{
private:
using Task = std::function<void()>;
    std::thread::id _thread_id;         //绑定的线程的id
    std::vector<Task> _queue;           //任务队列
    std::mutex _mutex;                  //保证任务队列的安全
    Poller _poller;                     //用于事件监控
    int _eventfd;                       //用于事件通知
    Channel* _eventfd_channel;          //管理eventfd的事件
    TimerWheel _timer_wheel;            //超时管理模块
private:
    void RunAllTask()
    {
        std::vector<Task> tasks;
        {
            std::unique_lock<std::mutex> lock(_mutex); //加锁
            tasks.swap(_queue);                        //取任务
        }
        for(auto&f:tasks)
        f();                                           //执行任务
    }
    bool IsInLoop()const {return std::this_thread::get_id() == _thread_id ;} 
    void PushTask(const Task& f)
    {
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _queue.push_back(f);
        }
        WakeUp();
    }
    static int CreateEventfd()          //用于创建一个 eventfd
    {
        int fd = eventfd(0,EFD_CLOEXEC|EFD_NONBLOCK);
        if(fd==-1)
        {
            ERROR_LOG("create eventfd failed");
            abort();
        }
        return fd;
    }
    void EventReadCallBack()const
    {
        uint64_t cnt = 0;
        int ret = read(_eventfd,&cnt,sizeof cnt);
        if(ret<0)
        {
            if(errno ==EAGAIN ||errno==EWOULDBLOCK ||errno ==EINTR) return;
            ERROR_LOG("read eventfd failed");
        }
        return;
    }
public:                             //对外提供的功能接口
    EventLoop():_thread_id(std::this_thread::get_id()),_eventfd(CreateEventfd()),_eventfd_channel(new Channel(_eventfd,this)),_timer_wheel(this)
    {
        _eventfd_channel->SetReadCallBack(std::bind(&EventLoop::EventReadCallBack,this));   //设置读回调函数
        _eventfd_channel->EnableRead();                     //启动读事件监听
    }
    void UpdateEvent(Channel* channel)
    {
        _poller.UpdateEvents(channel);
    }
    void RemoveEvent(Channel* channel)
    {
        _poller.Remove(channel);
    }
    void RunInLoop(const Task& f)
    {
        if(IsInLoop()) f();     //如果是绑定的线程就直接执行
        else PushTask(f);
    }
    void Start()
    {
        while(1)
        {
            //1 监听事件
            std::vector<Channel*> actives;
            int ret = _poller.Poll(&actives);    
            //2 执行IO回调
            for(auto channel:actives) channel->HandlerEvents();
            //3 执行任务队列的任务
            RunAllTask();
        }
    }
    void WakeUp()                  //唤醒EventLoop线程
    {
        uint64_t val = 1;
        int ret = write(_eventfd,&val,sizeof val);
        if(ret < 0)
        {
            if(errno == EAGAIN ||errno == EWOULDBLOCK ||errno==EINTR) return;
            ERROR_LOG("WakeUp failed");
            abort();
        }
        return;
    }
    ~EventLoop(){delete _eventfd_channel;}
    void AddTimerTask(uint64_t id , uint64_t delay,Task f)
    {
        _timer_wheel.AddTimerTask(id,delay,f);
    }
    void RefreshTimerTask(uint64_t id)
    {
        _timer_wheel.RefreshTimerTask(id);
    }
    void CancelTimerTask(uint64_t id)
    {
        _timer_wheel.CancelTimerTask(id); 
    }
};

